package com.org.khtn.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import com.google.common.collect.Multimap;
import com.org.khtn.command.Anncouncement;
import com.org.khtn.command.Command;
import com.org.khtn.data.Manager;

public class Server {

	private static JPanel contentPane;
	private static MyMenuBar menuBar;
	private static JSplitPane explorerContentSplitPane;
	private static Content_TabbedPopupMenu tabbedPopupMenu;
	private static Explorer_DatabasesPopupMenu explorerDatabasesPopupMenu;
	private static Explorer_UserDatabasePopupMenu explorerUserDatabasePopupMenu;
	private static Explorer_TablesPopupMenu explorerTablesPopupMenu;
	private static Explorer_UserTablePopupMenu explorerUserTablePopupMenu;
	private static Content_QueryContentPopupMenu queryContentPopupMenu;
	private static Content_TableDesignPopupMenu tableDesignPopupMenu;
	private static Content_TableSetValuePopupMenu tableSetValuePopupMenu;
	private static MyExplorer treeExplorer;
	private static MyToolBar toolBar;
	private static JTabbedPane contentTabbedPane;
	private static JFileChooser saveChooser;
	private static JFileChooser openChooser;
	private static Manager manager;

	private static void createAndShowGUI() {
		try {
			UIManager
					.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		openChooser = new JFileChooser();
		// openChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		openChooser.setFileFilter(new QueryFilter());
		openChooser.setAcceptAllFileFilterUsed(false);
		saveChooser = new JFileChooser();
		saveChooser.setFileFilter(new QueryFilter());
		saveChooser.setAcceptAllFileFilterUsed(false);

		JFrame frame = new JFrame("Server");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		menuBar = new MyMenuBar();
		frame.setJMenuBar(menuBar);

		explorerDatabasesPopupMenu = new Explorer_DatabasesPopupMenu();
		explorerUserDatabasePopupMenu = new Explorer_UserDatabasePopupMenu();
		explorerTablesPopupMenu = new Explorer_TablesPopupMenu();
		explorerUserTablePopupMenu = new Explorer_UserTablePopupMenu();

		tabbedPopupMenu = new Content_TabbedPopupMenu();
		queryContentPopupMenu = new Content_QueryContentPopupMenu();
		tableDesignPopupMenu = new Content_TableDesignPopupMenu();
		tableSetValuePopupMenu = new Content_TableSetValuePopupMenu();

		contentPane = (JPanel) frame.getContentPane();
		contentPane.setLayout(new BorderLayout());

		treeExplorer = new MyExplorer(manager.getAllDatabase());
		ImageIcon serverIcon = createImageIcon("server");
		ImageIcon databaseIcon = createImageIcon("database");
		ImageIcon databasesIcon = createImageIcon("databases");
		ImageIcon tablesIcon = createImageIcon("tables");
		ImageIcon tableIcon = createImageIcon("table");
		if (serverIcon != null && databaseIcon != null && tableIcon != null) {
			treeExplorer.setCellRenderer(new TreeRender(serverIcon,
					databaseIcon, databasesIcon, tablesIcon, tableIcon));
		} else {
			System.err.println("icon missing!");
		}
		treeExplorer.addMouseListener(new TreePopupListener(treeExplorer,
				explorerDatabasesPopupMenu, explorerUserDatabasePopupMenu,
				explorerTablesPopupMenu, explorerUserTablePopupMenu));

		contentTabbedPane = new JTabbedPane();

		explorerContentSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
				new JScrollPane(treeExplorer), contentTabbedPane);
		// splitPane.setOneTouchExpandable(false);
		explorerContentSplitPane.setDividerLocation(250);

		toolBar = new MyToolBar(manager.getAllDatabaseName());
		contentPane.add(toolBar, BorderLayout.PAGE_START);
		contentPane.add(explorerContentSplitPane, BorderLayout.CENTER);

		frame.setSize(new Dimension(900, 600));
		frame.setExtendedState(Frame.MAXIMIZED_BOTH);
		frame.setVisible(true);
	}

	public static ImageIcon createImageIcon(String name) {
		String location = "res/images/" + name + ".gif";
		return new ImageIcon(location);
	}

	public static JPanel makeTableDesignPanel() {
		JPanel designPanel = new JPanel(new BorderLayout());
		return designPanel;
	}

	public static void createNewQuery() {
		QueryTab.number++;
		QueryTab splitPane = new QueryTab(queryContentPopupMenu, "");
		contentTabbedPane.addTab("Query " + QueryTab.number, splitPane);
		contentTabbedPane.setSelectedComponent(splitPane);
		contentTabbedPane.setComponentPopupMenu(tabbedPopupMenu);
	}
	
	public static void showResultPanel() {
		QueryTab queryTab = (QueryTab) (contentTabbedPane
				.getSelectedComponent());
		queryTab.setDividerLocation(0.3);
		JPanel resultPanel = queryTab.resultPanel;
		resultPanel.setVisible(true);
	}

	public static int getNumberTable(Vector result) {
		int kq = 0;
		for (int i = 0; i < result.size(); i++) {
			if (result.elementAt(i) instanceof Map) {
				String error = getError((Map)result.elementAt(i));
				if (error == null) {
					kq++;
				}
			}
		}
		System.out.println(kq);
		return kq;
	}

	public static JSplitPane createMultiSplitPane(int nTab, int totalSize) {
		if (nTab == 0) {
			return null;
		}
		int height = totalSize/nTab;
		JSplitPane result = new JSplitPane();
		result.setOrientation(JSplitPane.VERTICAL_SPLIT);
		if (nTab == 1) {
			result.setDividerSize(0);
			result.setDividerLocation(height);
			result.setResizeWeight(0.5);
			result.setRightComponent(null);
		} else if (nTab >= 2) {
			JSplitPane temp = result;
			temp.setDividerLocation(height);
			temp.setResizeWeight(0.5);
			for (int i = 0; i < nTab - 2; i++) {
				JSplitPane sp = new JSplitPane();
				temp.setRightComponent(sp);
				sp.setDividerLocation(height);
				sp.setResizeWeight(0.5);
				sp.setOrientation(JSplitPane.VERTICAL_SPLIT);
				temp = sp;
			}
		}
		return result;
	}
	
	public static void showResultTable(JSplitPane sp, Map hm, int position,
			int nTab) {
		if (nTab == 0) {
			return;
		}
		QueryTab queryTab = (QueryTab) (contentTabbedPane
				.getSelectedComponent());
		JTable table = new JTable(new MyTableModel(hm));
		table.setFillsViewportHeight(false);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setCellSelectionEnabled(true);
		table.getColumnModel().getColumn(0).setPreferredWidth(30);
		JScrollPane js = new JScrollPane(table);
		JSplitPane temp = sp;
		if (position < nTab) {

			for (int i = 0; i < position - 1; i++) {
				temp = (JSplitPane) temp.getRightComponent();
			}
			temp.setLeftComponent(js);
		} else if (position == nTab) {
			if (nTab == 1) {
				temp.setLeftComponent(js);
			} else {
				for (int i = 0; i < position - 2; i++) {
					temp = (JSplitPane) temp.getRightComponent();
				}
				temp.setRightComponent(js);
			}
		}
	}

	public static void showResult(Map hm) {
		QueryTab queryTab = (QueryTab) (contentTabbedPane
				.getSelectedComponent());

		JPanel resultPanel = queryTab.resultPanel;
		if (resultPanel.isVisible() == false) {
			queryTab.setDividerLocation(0.5);
			resultPanel.setVisible(true);
		}
		JTable table = new JTable(new MyTableModel(hm));
		table.setFillsViewportHeight(false);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setCellSelectionEnabled(true);
		table.getColumnModel().getColumn(0).setPreferredWidth(30);
		JScrollPane js = new JScrollPane(table);

		JPanel resultTab = queryTab.resultTab;
		if (resultTab.getComponentCount() > 0) {
			resultTab.removeAll();
		}
		resultTab.add(js, BorderLayout.CENTER);
		resultTab.updateUI();
	}

	public static void openQuery(String path, String tabName) {
		JSplitPane splitPane = new QueryTab(queryContentPopupMenu, path);
		contentTabbedPane.addTab(tabName, splitPane);
		contentTabbedPane.setSelectedComponent(splitPane);
		contentTabbedPane.setComponentPopupMenu(tabbedPopupMenu);
	}

	public static class ItemListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			String str = e.getActionCommand();
			if (str.equals("toolbar_newquery")) {
				createNewQuery();
			} else if (str.equals("toolbar_execute")) {
				if (contentTabbedPane.getComponentCount() > 0) {
					if (contentTabbedPane.getSelectedComponent() instanceof QueryTab) {
						QueryTab queryTab = (QueryTab) contentTabbedPane
								.getSelectedComponent();
						try {
							String strCommand ="";
							if (queryTab.queryContentArea.getSelectedText() == null) {
								strCommand = queryTab.queryContentArea
										.getText();
							} else {
								strCommand = queryTab.queryContentArea
										.getSelectedText();
							}
							queryTab.messageAreaTab.setText("");
							JPanel resultTab = queryTab.resultTab;
							resultTab.removeAll();
							resultTab.updateUI();
							Command command = new Command(strCommand, toolBar.selectDB.getSelectedItem().toString());
							Vector returnVal = new Vector();
							returnVal = command.execute();
							if (queryTab.resultPanel.isVisible() == false
									&& queryTab.queryContentArea.getText()
											.compareToIgnoreCase("") != 0) {
								showResultPanel();
							}
							
							int nTab = getNumberTable(returnVal);
							
							JSplitPane sp = createMultiSplitPane(nTab, queryTab.getHeight() - queryTab.getDividerLocation() - 45);
							if (sp != null) {
								resultTab.add(sp);
							}
							int numError = 0;
							int position = 0;
							for (int i = 0; i < returnVal.size(); i++) {
								if (returnVal.elementAt(i) instanceof Map) {
									Map result = (Map) returnVal.elementAt(i);
									String error = getError(result);
									if (error == null) {
										position++;
										showResultTable(sp, result, position, nTab);
									} else {
										numError++;
										appendMessage(queryTab.messageAreaTab,
												error);
									}
								} else if (returnVal.elementAt(i) instanceof Integer) {
									int code = (int) returnVal.elementAt(i);
									System.out.println(code);
									if (code > 0) {
										appendMessage(queryTab.messageAreaTab,
												code + " row(s) affected");
									} else {
										switch (code) {
										case -10:
											appendMessage(
													queryTab.messageAreaTab,
													Anncouncement.ERROR_SYNTAX
															.getDescription());
											break;
										case -11:
											appendMessage(
													queryTab.messageAreaTab,
													Anncouncement.ERROR_TABLE_EXIST
															.getDescription());
											break;
										case -12:
											appendMessage(
													queryTab.messageAreaTab,
													Anncouncement.ERROR_FIELD_EXIST
															.getDescription());
											break;
										case -21:
											appendMessage(
													queryTab.messageAreaTab,
													Anncouncement.ERROR_INSERT_FEWER
															.getDescription());
											break;
										case -22:
											appendMessage(
													queryTab.messageAreaTab,
													Anncouncement.ERROR_INSERT_MORE
															.getDescription());
											break;
										case -23:
											appendMessage(
													queryTab.messageAreaTab,
													Anncouncement.ERROR_INSERT_PRIMARYKEYDUB
															.getDescription());
											break;
										case -13:
											appendMessage(
													queryTab.messageAreaTab,
													Anncouncement.ERROR_CONVERT_TO_INT
															.getDescription());
											break;
										}
										numError++;
									}
								}
							}
							if(numError >0) {
								queryTab.notice.setForeground(Color.red);
								queryTab.notice.setText("Query completed with errors!");
							} else {
								queryTab.notice.setForeground(Color.black);
								queryTab.notice.setText("Query executed successfully!");
							}
							resultTab.updateUI();
						} catch (Exception ex) {
							ex.printStackTrace();
						}
					}
				}
			} else if (str.equals("toolbar_open")) {
				int returnVal = openChooser.showOpenDialog(null);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
					String path = openChooser.getSelectedFile()
							.getAbsolutePath();
					String name = openChooser.getSelectedFile().getName();
					openQuery(path, name);
				}
			} else if (str.equals("explorer_newdatabase")) {

				String databaseName = "";
				do {
					databaseName = JOptionPane
							.showInputDialog("Nhập tên database");
					if (databaseName == null) {
						break;
					}
					if (databaseName.compareToIgnoreCase("") == 0) {
						JOptionPane.showMessageDialog(null,
								"Vui lòng nhập tên database!");
					} else if (checkDatabaseExist(databaseName)) {
						JOptionPane.showMessageDialog(null, "Tên database "
								+ databaseName + " bị trùng!");
					}
				} while (databaseName != null
						&& (checkDatabaseExist(databaseName) || databaseName
								.compareToIgnoreCase("") == 0));

				if (databaseName != null && databaseName != "") {
					toolBar.selectDB.addItem(databaseName);
					TreePath path = treeExplorer.getSelectionPath();
					DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
							.getLastPathComponent();
					treeExplorer.insertNode(node, databaseName);
					manager.createDatabase(databaseName, databaseName,
							"mytest\\data\\");
				}
			} else if (str.equals("explorer_refreshdatabase")) {
				System.out.println("explorer_refreshdatabase");
			} else if (str.equals("explorer_newquery")) {
				System.out.println("explorer_newquery");
				createNewQuery();
				TreePath path = treeExplorer.getSelectionPath();
				String dbName = path.getLastPathComponent().toString();
				toolBar.selectDB.setSelectedItem(dbName);
			} else if (str.equals("explorer_deletedatabase")) {
				System.out.println("explorer_deletedatabase");
				if (JOptionPane.showConfirmDialog(null,
						"Bạn có muốn xóa Database?", "Warning!",
						JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
					TreePath selectPath = treeExplorer.getSelectionPath();
					String dbName = selectPath.getLastPathComponent()
							.toString();
					System.out.println(dbName);
					toolBar.selectDB.removeItem(dbName);
					Vector dsTableName = manager.getAllTableName(dbName);
					for (int i = 0; i < dsTableName.size(); i++) {
						String tbName = (String) dsTableName.elementAt(i);
						int index = contentTabbedPane.indexOfTab(dbName + "-"
								+ tbName);
						if (index != -1) {
							contentTabbedPane.removeTabAt(index);
						}
					}
					DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectPath
							.getLastPathComponent();
					treeExplorer.deleteNode(node);
					manager.removeDatabase(selectPath.getLastPathComponent()
							.toString());
				}
			} else if (str.equals("explorer_newtable")) {
				System.out.println("explorer_newtable");
				TableTab.number++;
				TableTab panel = new TableTab(tableDesignPopupMenu,
						treeExplorer.getSelectionPath().getParentPath()
								.getLastPathComponent().toString(), "Table "
								+ TableTab.number,
						treeExplorer.getSelectionPath());
				contentTabbedPane.addTab(panel.tableName, panel);
				contentTabbedPane.setSelectedComponent(panel);
				contentTabbedPane.setComponentPopupMenu(tabbedPopupMenu);
			} else if (str.equals("explorer_designtable")) {
				System.out.println("explorer_designtable");
				String tableName = treeExplorer.getSelectionPath()
						.getLastPathComponent().toString();
				String databaseName = treeExplorer.getSelectionPath()
						.getParentPath().getParentPath().getLastPathComponent()
						.toString();
				if (!checkTabbedPaneContainName(databaseName + "-" + tableName)) {
					manager.createTempDatabase(databaseName);
					TableTab panel = new TableTab(manager.getTableDefines(
							databaseName, tableName), tableDesignPopupMenu,
							databaseName, tableName,
							treeExplorer.getSelectionPath(), manager,
							manager.getTablePrimaryKey(databaseName, tableName));
					MyTableDesign td = (MyTableDesign) panel.table.getModel();
					td.isModify = true;
					contentTabbedPane.addTab(databaseName + "-" + tableName,
							panel);
					contentTabbedPane.setSelectedComponent(panel);
					contentTabbedPane.setComponentPopupMenu(tabbedPopupMenu);
				}
			} else if (str.equals("explorer_edittable")) {
				System.out.println("explorer_edittable");
				String tableName = treeExplorer.getSelectionPath()
						.getLastPathComponent().toString();
				String databaseName = treeExplorer.getSelectionPath()
						.getParentPath().getParentPath().getLastPathComponent()
						.toString();
				if (!checkTabbedPaneContainName(databaseName + "-" + tableName)) {
					TableTab panel = new TableTab(manager.getAllTableRecord(
							databaseName, tableName), manager.getTableDefines(
							databaseName, tableName), tableSetValuePopupMenu,
							databaseName, tableName,
							treeExplorer.getSelectionPath(),
							manager.getTablePrimaryKey(databaseName, tableName));
					contentTabbedPane.addTab(databaseName + "-" + tableName,
							panel);
					contentTabbedPane.setSelectedComponent(panel);
					contentTabbedPane.setComponentPopupMenu(tabbedPopupMenu);
				}

			} else if (str.equals("explorer_deletetable")) {
				System.out.println("explorer_deletetable");
				if (JOptionPane.showConfirmDialog(null,
						"Bạn có muốn xóa Table?", "Warning!",
						JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
					TreePath selectPath = treeExplorer.getSelectionPath();
					String tableName = selectPath.getLastPathComponent()
							.toString();
					String databaseName = selectPath.getParentPath()
							.getParentPath().getLastPathComponent().toString();
					DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectPath
							.getLastPathComponent();
					treeExplorer.deleteNode(node);
					manager.removeTable(databaseName, tableName);

					int index = contentTabbedPane.indexOfTab(databaseName + "-"
							+ tableName);
					if (index != -1) {
						contentTabbedPane.removeTabAt(index);
					}
				}
			} else if (str.equals("content_savetab")
					|| str.equals("toolbar_save")) {
				System.out.println("content_savetab");
				if (contentTabbedPane.getSelectedComponent() instanceof QueryTab) {
					QueryTab queryTab = (QueryTab) (contentTabbedPane
							.getSelectedComponent());
					if (queryTab.location == "") {
						String fildName = contentTabbedPane
								.getTitleAt(contentTabbedPane
										.getSelectedIndex());
						saveChooser.setSelectedFile(new File(fildName));
						int returnVal = saveChooser.showSaveDialog(null);
						if (returnVal == JFileChooser.APPROVE_OPTION) {
							String path = saveChooser.getSelectedFile()
									.getAbsolutePath();
							String name = saveChooser.getSelectedFile()
									.getName();
							if (!(path.endsWith(".query"))) {
								path += ".query";
								name += ".query";
							}
							queryTab.location = path;
							try {
								FileOutputStream fout = new FileOutputStream(
										new File(path));
								BufferedWriter bw = new BufferedWriter(
										new OutputStreamWriter(fout, "UTF-16"));
								bw.append(queryTab.queryContentArea.getText());
								bw.close();
								fout.close();
							} catch (Exception ex) {
							}
							contentTabbedPane.setTitleAt(
									contentTabbedPane.getSelectedIndex(), name);
						}
					} else {
						try {
							FileOutputStream fout = new FileOutputStream(
									new File(queryTab.location));
							BufferedWriter bw = new BufferedWriter(
									new OutputStreamWriter(fout, "UTF-16"));
							bw.append(queryTab.queryContentArea.getText());
							bw.close();
							fout.close();
						} catch (Exception ex) {
						}
					}
				} else if (contentTabbedPane.getSelectedComponent() instanceof TableTab) {
					System.out.println("Table");

					TableTab tableTab = (TableTab) (contentTabbedPane
							.getSelectedComponent());
					if (tableTab.table.getModel() instanceof MyTableDesign) {
						MyTableDesign model = (MyTableDesign) tableTab.table
								.getModel();
						if (model.checkAllColumnHasName() == false) {
							JOptionPane
									.showMessageDialog(null,
											"Vui lòng nhập Column Name cho tất cả các cột!");
						} else if (model.checkSameColumnName()) {
							JOptionPane.showMessageDialog(null,
									"Column Name không được giống nhau!");
						} else {
							String dbName = tableTab.databaseName;
							String tableName = tableTab.tableName;
							if (tableTab.isSave == false) {
								DefaultMutableTreeNode node = (DefaultMutableTreeNode) tableTab.selectionPath
										.getLastPathComponent();
								do {
									tableName = JOptionPane.showInputDialog(
											"Nhập tên bảng", tableName);
									if (tableName == null) {
										break;
									}
									if (tableName.compareToIgnoreCase("") == 0) {
										JOptionPane.showMessageDialog(null,
												"Vui lòng nhập tên table!");
									} else if (checkTableExist(dbName,
											tableName)) {
										JOptionPane.showMessageDialog(null,
												"Tên table " + tableName
														+ " bị trùng!");
									}
								} while (tableName != null
										&& (checkTableExist(dbName, tableName) || tableName
												.compareToIgnoreCase("") == 0));

								if (tableName != null && tableName != "") {
									treeExplorer.insertNode(node, tableName);
									manager.createTable(dbName, tableName);
									for (int i = 0; i < model.getRowCount(); i++) {
										manager.createTableField(
												dbName,
												tableName,
												(String) model.getValueAt(i, 1),
												(String) model.getValueAt(i, 2));
									}
									tableTab.isSave = true;
									tableTab.tableName = tableName;
									contentTabbedPane.setTitleAt(
											contentTabbedPane
													.getSelectedIndex(), dbName
													+ "-" + tableName);
									Vector v = new Vector();
									for (int i = 0; i < tableTab.primaryKeys
											.size(); i++) {
										v.add(model.getValueAt(
												(int) tableTab.primaryKeys
														.elementAt(i), 1));
									}
									System.out.println(v);
									manager.setTablePrimaryKey(
											tableTab.databaseName, tableName, v);
								}
							} else {
								if (model.checkAllColumnHasName() == false) {
									JOptionPane
											.showMessageDialog(null,
													"Vui lòng nhập Column Name cho tất cả các cột!");
								} else if (model.checkSameColumnName()) {
									JOptionPane
											.showMessageDialog(null,
													"Column Name không được giống nhau!");
								} else {
									for (int i = 0; i < tableTab.table
											.getRowCount(); i++) {
										String fieldName = (String) tableTab.table
												.getValueAt(i, 1);
										String fieldType = (String) tableTab.table
												.getValueAt(i, 2);
										manager.editTableFieldType(
												tableTab.databaseName,
												tableTab.tableName, fieldName,
												fieldType);
									}
									Vector v = new Vector();
									for (int i = 0; i < tableTab.primaryKeys
											.size(); i++) {
										v.add(model.getValueAt(
												(int) tableTab.primaryKeys
														.elementAt(i), 1));
									}
									System.out.println(v);
									manager.setTablePrimaryKey(
											tableTab.databaseName, tableName, v);
								}
								manager.deleteBackupDatabase(tableTab.databaseName);
								manager.createTempDatabase(tableTab.databaseName);
							}
						}
					} else if (tableTab.table.getModel() instanceof MyTableSetValue) {
						tableTab.table.editCellAt(
								tableTab.table.getSelectedRow(), 0);
						String dbName = tableTab.databaseName;
						String tbName = tableTab.tableName;
						MyTableSetValue model = (MyTableSetValue) tableTab.table
								.getModel();
						Map<String, String> tableDefines = manager
								.getTableDefines(dbName, tbName);
						int result = checkAllowSaveRecord(model, tableDefines);
						boolean rsPrimaryKey = checkHasSameValueInPrimaryKey(model,tableTab.primaryKeys);
						if (result == -1) {
							JOptionPane.showMessageDialog(null,
									"Số lượng các cột đã thay đổi!");
						} else if (result == 0) {
							JOptionPane.showMessageDialog(null,
									"Giá trị không phù hợp với kiểu!");
						} else if (rsPrimaryKey) {
							JOptionPane.showMessageDialog(null,
									"Trùng giá trị ở khóa chính!");
						} else if (result == 1) {
							manager.removeAllTableRecord(dbName, tbName);
							for (int i = 0; i < model.getRowCount(); i++) {
								String[] value = new String[model
										.getColumnCount() - 1];
								String[] name = new String[model
										.getColumnCount() - 1];
								for (int j = 1; j < model.getColumnCount(); j++) {
									value[j - 1] = model.getValueAt(i, j)
											.toString();
									name[j - 1] = model.getColumnName(j);
								}

								manager.insertRecord(dbName, tbName, name,
										value);
							}
							System.out.println(model.getRowCount());
						}
					}
				}
			} else if (str.equals("content_closetab")) {
				if (contentTabbedPane.getSelectedComponent() instanceof TableTab) {
					TableTab tableTab = (TableTab) (contentTabbedPane
							.getSelectedComponent());
					if (tableTab.table.getModel() instanceof MyTableDesign) {
						MyTableDesign model = (MyTableDesign) tableTab.table
								.getModel();
						if (model.isModify) {
							manager.backupDatabase(tableTab.databaseName);
							if (hasTableModify(tableTab.databaseName,
									contentTabbedPane.getSelectedIndex())) {
								manager.createTempDatabase(tableTab.databaseName);
							}
						}
					}
				}
				contentTabbedPane.remove(contentTabbedPane
						.getSelectedComponent());
			} else if (str.equals("content_closeallbutthistab")) {
				for (int i = contentTabbedPane.getTabCount() - 1; i >= 0; i--) {
					if (i != contentTabbedPane.getSelectedIndex()) {
						if (contentTabbedPane.getComponent(i) instanceof TableTab) {
							TableTab tableTab = (TableTab) (contentTabbedPane
									.getComponent(i));
							if (tableTab.table.getModel() instanceof MyTableDesign) {
								MyTableDesign model = (MyTableDesign) tableTab.table
										.getModel();
								if (model.isModify) {
									manager.backupDatabase(tableTab.databaseName);
									if (hasTableModify(tableTab.databaseName, i)) {
										manager.createTempDatabase(tableTab.databaseName);
									}
								}
							}
						}
						contentTabbedPane.remove(contentTabbedPane
								.getComponentAt(i));
					}
				}
			} else if (str.equals("content_cutquery")) {
				QueryTab queryTab = (QueryTab) (contentTabbedPane
						.getSelectedComponent());
				queryTab.queryContentArea.cut();
			} else if (str.equals("content_copyquery")) {
				QueryTab queryTab = (QueryTab) (contentTabbedPane
						.getSelectedComponent());
				queryTab.queryContentArea.copy();
			} else if (str.equals("content_pastequery")) {
				QueryTab queryTab = (QueryTab) (contentTabbedPane
						.getSelectedComponent());
				queryTab.queryContentArea.paste();
			} else if (str.equals("content_executequery")) {
				System.out.println("content_executequery");
			} else if (str.equals("content_setprimarykey")) {
				TableTab tableTab = (TableTab) (contentTabbedPane
						.getSelectedComponent());
				int[] row = tableTab.table.getSelectedRows();
				if (row.length >= 0) {
					MyTableDesign model = (MyTableDesign) tableTab.table
							.getModel();
					if (model.checkValueAt(row, 1)) {
						RowHeaderRenderer rowHeader = (RowHeaderRenderer) tableTab.table
								.getCellRenderer(0, 0);
						Vector v = new Vector();
						for (int i = 0; i < row.length; i++) {
							v.add(row[i]);
						}
						rowHeader.setPrimaryKey(v);
						tableTab.primaryKeys = v;
						tableTab.table.updateUI();
					} else {
						JOptionPane.showMessageDialog(null,
								"Vui lòng nhập Column Name trước!");
					}
				}
			} else if (str.equals("content_removeprimarykey")) {
				TableTab tableTab = (TableTab) (contentTabbedPane
						.getSelectedComponent());
				MyTableDesign model = (MyTableDesign) tableTab.table.getModel();
				RowHeaderRenderer rowHeader = (RowHeaderRenderer) tableTab.table
						.getCellRenderer(0, 0);
				rowHeader.removePrimaryKey();
				tableTab.primaryKeys.removeAllElements();
				tableTab.table.updateUI();
			} else if (str.equals("content_insertcolumnafter")) {
				TableTab tableTab = (TableTab) (contentTabbedPane
						.getSelectedComponent());
				MyTableDesign model = (MyTableDesign) tableTab.table.getModel();
				if (model.isModify && tableTab.table.getSelectedRow() != -1) {
					manager.insertTableField(tableTab.databaseName,
							tableTab.tableName, "", "int");
				}
				
				int n = tableTab.table.getSelectedRow();
				Vector keys = tableTab.primaryKeys;
				for (int i=0; i<keys.size(); i++) {
					int pos = (int)keys.elementAt(i);
					if (pos > n) {
						pos++;
						keys.setElementAt(pos, i);
					}
				}
				model.insertNewRowBelow();
				RowHeaderRenderer rowHeader = (RowHeaderRenderer) tableTab.table
						.getCellRenderer(0, 0);
				rowHeader.setPrimaryKey(keys);
				tableTab.primaryKeys = keys;
				tableTab.table.updateUI();
			} else if (str.equals("content_insertcolumnbefore")) {
				TableTab tableTab = (TableTab) (contentTabbedPane
						.getSelectedComponent());
				MyTableDesign model = (MyTableDesign) tableTab.table.getModel();
				if (model.isModify && tableTab.table.getSelectedRow() != -1) {
					manager.insertTableField(tableTab.databaseName,
							tableTab.tableName, "", "int");
				}
				int n = tableTab.table.getSelectedRow();
				Vector keys = tableTab.primaryKeys;
				for (int i=0; i<keys.size(); i++) {
					int pos = (int)keys.elementAt(i);
					if (pos >= n) {
						pos++;
						keys.setElementAt(pos, i);
					}
				}
				model.insertNewRowAbove();
				RowHeaderRenderer rowHeader = (RowHeaderRenderer) tableTab.table
						.getCellRenderer(0, 0);
				rowHeader.setPrimaryKey(keys);
				tableTab.primaryKeys = keys;
				tableTab.table.updateUI();
			} else if (str.equals("content_deletecolumn")) {
				TableTab tableTab = (TableTab) (contentTabbedPane
						.getSelectedComponent());
				System.out.println(tableTab.table.getSelectedRow());
				MyTableDesign model = (MyTableDesign) tableTab.table.getModel();
				if (model.isModify && tableTab.table.getSelectedRow() != -1) {
					manager.removeTableField(
							tableTab.databaseName,
							tableTab.tableName,
							(String) model.getValueAt(
									tableTab.table.getSelectedRow(), 1));
				}
				int n = tableTab.table.getSelectedRow();
				Vector keys = tableTab.primaryKeys;
				for (int i=keys.size()-1; i>=0; i--) {
					int pos = (int)keys.elementAt(i);
					if (pos == n && pos != 0) {
						keys.removeElementAt(i);
					}else if (pos > n) {
						pos--;
						keys.setElementAt(pos, i);
					}
				}
				model.deleteSelectedRow();
				RowHeaderRenderer rowHeader = (RowHeaderRenderer) tableTab.table
						.getCellRenderer(0, 0);
				rowHeader.setPrimaryKey(keys);
				tableTab.primaryKeys = keys;
				tableTab.table.updateUI();
				
			} else if (str.equals("content_insertrecordafter")) {
				TableTab tableTab = (TableTab) (contentTabbedPane
						.getSelectedComponent());
				MyTableSetValue model = (MyTableSetValue) tableTab.table
						.getModel();
				model.insertNewRowBelow(tableTab.table.getSelectedRow());
			} else if (str.equals("content_insertrecordbefore")) {
				TableTab tableTab = (TableTab) (contentTabbedPane
						.getSelectedComponent());
				MyTableSetValue model = (MyTableSetValue) tableTab.table
						.getModel();
				model.insertNewRowAbove(tableTab.table.getSelectedRow());
			} else if (str.equals("content_deleterecord")) {
				TableTab tableTab = (TableTab) (contentTabbedPane
						.getSelectedComponent());
				MyTableSetValue model = (MyTableSetValue) tableTab.table
						.getModel();
				model.deleteRow(tableTab.table.getSelectedRow());
			}
		}
	}

	public static boolean checkTableExist(String dbName, String tbName) {
		Vector v = manager.getAllTableName(dbName);
		for (int i = 0; i < v.size(); i++) {
			String nameInDatabase = (String) v.elementAt(i);
			if (nameInDatabase.compareToIgnoreCase(tbName) == 0) {
				return true;
			}
		}
		return false;
	}

	public static boolean checkDatabaseExist(String dbName) {
		Vector v = manager.getAllDatabaseName();
		for (int i = 0; i < v.size(); i++) {
			String userDatabase = (String) v.elementAt(i);
			if (userDatabase.compareToIgnoreCase(dbName) == 0) {
				return true;
			}
		}
		return false;
	}

	public static boolean checkTabbedPaneContainName(String name) {
		for (int i = 0; i < contentTabbedPane.getTabCount(); i++) {
			String tabName = contentTabbedPane.getTitleAt(i);
			if (tabName.compareToIgnoreCase(name) == 0) {
				return true;
			}
		}
		return false;
	}

	public static boolean hasTableModify(String dbName, int index) {
		for (int i = 0; i < contentTabbedPane.getTabCount(); i++) {
			if (i != index) {
				if (contentTabbedPane.getComponent(i) instanceof TableTab) {
					TableTab tableTab = (TableTab) (contentTabbedPane
							.getComponent(i));
					if (tableTab.table.getModel() instanceof MyTableDesign) {
						MyTableDesign model = (MyTableDesign) tableTab.table
								.getModel();
						if (model.isModify
								&& (tableTab.databaseName
										.compareToIgnoreCase(dbName)) == 0) {
							return true;
						}
					}
				}
			}
		}
		System.out.println("aaa");
		return false;
	}

	public static int checkAllowSaveRecord(MyTableSetValue model,
			Map<String, String> tableDefines) {
		if (tableDefines.size() != model.getColumnCount() - 1) {
			return -1;
		} else {
			Vector type = new Vector();
			Vector fieldName = new Vector();
			for (Map.Entry<String, String> e : tableDefines.entrySet()) {
				type.add(e.getValue());
				fieldName.add(e.getKey());
			}
			for (int i = 0; i < model.getRowCount(); i++) {
				for (int j = 1; j < model.getColumnCount(); j++) {
					String value = model.getValueAt(i, j).toString();
					String field = model.getColumnName(j);
					int index = fieldName.indexOf(field);
					if (((String) type.elementAt(index))
							.compareToIgnoreCase("int") == 0) {
						try {
							Integer.parseInt(value);
						} catch (NumberFormatException nfe) {
							model.table.setRowSelectionInterval(i, i);
							model.table.editCellAt(i, j);
							return 0;
						}
					}
				}
			}
		}
		return 1;
	}
	
	public static boolean checkHasSameValueInPrimaryKey(MyTableSetValue model, Vector primaryKeys) {
		Vector col = new Vector();
		if (primaryKeys.size() > 0) {
			for (int i=0; i<model.getColumnCount(); i++) {
				if (primaryKeys.contains(model.getColumnName(i))) {
					col.add(i);
				}
			}
			
			for (int i=0; i<model.getRowCount(); i++) {
				for (int j=i+1; j<model.getRowCount(); j++) {
					Vector rowi = new Vector();
					Vector rowj = new Vector();
					for (int l=0; l<col.size(); l++) {
						rowi.add(model.getValueAt(i, (int)col.elementAt(l)));
						rowj.add(model.getValueAt(j, (int)col.elementAt(l)));
					}
					if (rowi.equals(rowj)) {
						model.table.setRowSelectionInterval(i, i);
						return true;
					}
				}
			}
		} else {
			return false;
		}
		return false;
	}

	public static boolean isNumber(String number) {
		try {
			Integer.parseInt(number);
		} catch (Exception ex) {
			return false;
		}
		return true;
	}
	
	public static void appendMessage(JTextArea messageArea, String message) {
		messageArea.append(message);
	}

	public static String getError(Map<String, Multimap<String, String>> m) {
		for (Map.Entry<String, Multimap<String, String>> e : m.entrySet()) {
			String key = e.getKey();
			Multimap<String, String> values = e.getValue();
			if (key.compareToIgnoreCase("error") == 0) {
				for (Entry<String, Collection<String>> entry : values.asMap()
						.entrySet()) {
					String att = (String) entry.getKey();
					List<String> value = new ArrayList<String>();
					value.addAll(entry.getValue());
					return value.get(0);
				}
			} else {
				return null;
			}
		}
		return null;
	}

	public static void main(String[] args) throws Exception {

		String port = "";
		do {
			port = JOptionPane
					.showInputDialog("Vui lòng nhập port lắng nghe các kết nối!");
			if (port == null) {
				break;
			}
			if (port.compareToIgnoreCase("") == 0) {
				JOptionPane.showMessageDialog(null,
						"Vui lòng nhập port lắng nghe các kết nối!");
			} else if (isNumber(port) == false) {
				JOptionPane.showMessageDialog(null,
						"Vui lòng nhập giá trị nguyên!");
			}
		} while (port != null
				&& (port.compareToIgnoreCase("") == 0 || isNumber(port) == false));

		if (port != null) {
			manager = new Manager("mytest\\data.json");
			createAndShowGUI();
			ServerSocket s = new ServerSocket(Integer.parseInt(port));
			do {
				Socket ss = s.accept(); // synchronous
				ProcessThread pt = new ProcessThread(ss,
						manager.getAllDatabaseName());
				pt.start();
			} while (true);
		}
	}
}
